package org.idea.spring.jdbc.xa;

import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import org.idea.spring.jdbc.xa.bean.MyXid;

import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author linhao
 * @date created in 11:18 上午 2020/10/30
 */
public class JTADatasourceDemo {


    private static final String INSERT_SQL_1 = "INSERT INTO `test-db01`.`t_order_1` (  `order_no`, `product_id`, `user_id`, `create_time`, `update_time` ) VALUES ( 39241, 1556586, 2662, now(), now() )";

    private static final String INSERT_SQL_2 = "INSERT INTO `test-db01`.`t_order_2`( `order_no`, `product_id`, `user_id`, `create_time`, `update_time`) VALUES ( 3562, 1137131, 3711, now(), now())";

    public static void main(String[] args) throws SQLException, XAException {
        //往表order_1表写入数据
        XADataSource xaDataSource_1 = getDatasource(DataSourceConfig.DATA_SOURCE_1);
        XAConnection xaConnection_1 = getXAConnection(xaDataSource_1);
        Connection connection_1 = getConnection(xaConnection_1);
        connection_1.setAutoCommit(false);
        Statement statement_1 = connection_1.createStatement();
        XAResource xaResource_1 = xaConnection_1.getXAResource();
        Xid xid_1 = new MyXid(100, new byte[]{0x07}, new byte[]{0x05});
        xaResource_1.start(xid_1, XAResource.TMNOFLAGS);
        statement_1.executeUpdate(INSERT_SQL_1);
        xaResource_1.end(xid_1, XAResource.TMSUCCESS);
        int ret_1 = xaResource_1.prepare(xid_1);


        //往order_2表写入数据
        XADataSource xaDataSource_2 = getDatasource(DataSourceConfig.DATA_SOURCE_2);
        XAConnection xaConnection_2 = getXAConnection(xaDataSource_2);
        Connection connection_2 = getConnection(xaConnection_2);
        connection_2.setAutoCommit(false);
        Statement statement_2 = connection_2.createStatement();
        XAResource xaResource_2 = xaConnection_2.getXAResource();
        Xid xid_2 = new MyXid(100, new byte[]{0x07}, new byte[]{0x06});
        xaResource_2.start(xid_2, XAResource.TMNOFLAGS);
        statement_2.executeUpdate(INSERT_SQL_2);
        xaResource_2.end(xid_2, XAResource.TMSUCCESS);
        int ret_2 = xaResource_2.prepare(xid_2);

        if (XAResource.XA_OK == ret_2 && XAResource.XA_OK == ret_1) {
            System.out.println("both success");
            xaResource_1.commit(xid_1, false);
            xaResource_2.commit(xid_2, false);
        } else {
            if(XAResource.XA_OK != ret_1){
                xaResource_1.rollback(xid_1);
            }
            if(XAResource.XA_OK != ret_2){
                xaResource_2.rollback(xid_2);
            }
            System.out.println("has error,need row back");
        }
        closeConnection(connection_1);
        closeConnection(connection_2);
    }


    /**
     * 获取请求链接
     *
     * @param dataSourceConfig
     * @return
     */
    public static XADataSource getDatasource(DataSourceConfig dataSourceConfig) {
        MysqlXADataSource dataSource = new MysqlXADataSource();
        dataSource.setPassword(dataSourceConfig.getPassword());
        dataSource.setUrl(dataSourceConfig.getUrl());
        dataSource.setUser(dataSourceConfig.getUsername());
        return dataSource;
    }

    public static Connection getConnection(XAConnection xaConnection) {
        Connection connection = null;
        try {
            connection = xaConnection.getConnection();
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    public static XAConnection getXAConnection(XADataSource xaDataSource) {
        XAConnection xaConnection = null;
        try {
            xaConnection = xaDataSource.getXAConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return xaConnection;
    }


    public static void closeConnection(Connection conn) {
        try {
            conn.close();
        } catch (SQLException e) {
            System.out.println("连接关闭失败");
        }
    }


}
